import { DataBase } from "./DataBase";
import UserDataHelper from "./UserDataHelper";

export class DataManager {
    /**数据 */
    private static data: any = {};
    /**应用id */
    private static appid: string = "";
    /**游戏名 */
    private static gameName: string = "";
    /**用户OpenId */
    private static openid: string = "";
    /**服务端与客户端时间差 */
    private static offsetTime: number = 0;

    /**
     * 初始化数据
     * @param appid 应用id
     * @param gameName 游戏名
     * @param openid 用户OpenId
     * @param isNet 是否联网获取存档
     * @param maxTime 最大获取时间，超时使用本地存档
     * @param callback 获取网络存档回调,返回参数status 1:成功 -1:失败 -2:超时使用本地存档
     * @param caller 回调作用域
     */

    public static Init(appid: string, gameName: string, openid: string, isNet: boolean = false, maxTime: number = 10, callback: Function = null, caller: { status: number } = null): void {
        this.appid = appid;
        this.gameName = gameName;
        this.openid = openid;

        if (isNet) {
            // 获取网络存档
            UserDataHelper.reqUserData(appid, gameName, openid, (code, msg, timestamp) => {
                if (maxTime <= -1) return;
                let userData = null;
                this.offsetTime = new Date().getTime() - timestamp;
                if (code == 0 && msg && msg.length > 0) {
                    try {
                        let data = JSON.parse(msg);
                        if (data.hasOwnProperty("userData")) {
                            if (data.userData.length > 2) {
                                userData = JSON.parse(data.userData);
                            }
                        }
                    } catch (error) { console.warn("【获取服务端存档】失败!", error); }
                }

                if (!!userData) {
                    // 有网络存档
                    if (userData.hasOwnProperty("saveTime")) {
                        // 网络存档有效，对比网络存档时间与本地存档时间
                        let serverTime = userData["saveTime"];
                        let localTime = parseInt(localStorage.getItem("saveTime") || '0');
                        if (serverTime >= localTime) {
                            // 使用网络存档
                            this.data = userData;
                            this.data["saveTime"] = timestamp;
                            if (!!callback) {
                                if (!!caller) {
                                    callback.call(caller, 1);
                                } else {
                                    callback(1);
                                }
                            }
                        } else {
                            // 使用本地存档
                            let data = localStorage.getItem(gameName);
                            if (data == null) {
                                this.data = {};
                            } else {
                                this.data = JSON.parse(data || "{}");
                            }
                            this.data["saveTime"] = timestamp;
                            if (!!callback) {
                                if (!!caller) {
                                    callback.call(caller, 1);
                                } else {
                                    callback(1);
                                }
                            }
                        }
                    } else {
                        // 网络存档无效，获取本地存档
                        let data = localStorage.getItem(gameName);
                        if (data == null) {
                            this.data = {};
                        } else {
                            this.data = JSON.parse(data || "{}");
                        }
                        this.data["saveTime"] = timestamp;
                        if (!!callback) {
                            if (!!caller) {
                                callback.call(caller, 1);
                            } else {
                                callback(1);
                            }
                        }
                    }
                } else if (userData == '') {
                    // 无网络存档，获取本地存档
                    let data = localStorage.getItem(gameName);
                    if (data == null) {
                        this.data = {};
                    } else {
                        this.data = JSON.parse(data || "{}");
                    }
                    this.data["saveTime"] = timestamp;
                    if (!!callback) {
                        if (!!caller) {
                            callback.call(caller, 1);
                        } else {
                            callback(1);
                        }
                    }
                } else {
                    if (!!callback) {
                        if (!!caller) {
                            callback.call(caller, -1);
                        } else {
                            callback(-1);
                        }
                    }
                    console.warn("【获取服务端存档】失败!");
                }
                isNet = false;
            });
            setTimeout(() => {
                if (isNet) {
                    // 联网超时，使用本地存档
                    let data = localStorage.getItem(gameName);
                    if (data == null) {
                        this.data = {};
                    } else {
                        this.data = JSON.parse(data || "{}");
                    }

                    if (!!callback) {
                        if (!!caller) {
                            callback.call(caller, -2);
                        } else {
                            callback(-2);
                        }
                    }
                    maxTime = -1;
                }
            }, maxTime * 1000)
        } else {
            // 获取本地存档
            let data = localStorage.getItem(gameName);
            if (data == null) {
                this.data = {};
            } else {
                this.data = JSON.parse(data || "{}");
            }

            if (!!callback) {
                if (!!caller) {
                    callback.call(caller, 1);
                } else {
                    callback(1);
                }
            }
        }
    }

    /**
     * 加载存档
     * @param key 存档键值
     * @param data 存档数据 
     */
    public static LoadData(key: string, data: string = null) {
        if (data == null) {
            this.data = {};
        } else {
            this.data = JSON.parse(localStorage.getItem(key) || "{}");
        }
    }

    /**
     * 设置数据
     * @param key 
     * @param value 
     */
    public static SetData(key: string, value: any): void {
        this.data[key] = value;
        let saveTime = new Date().getTime() - this.offsetTime;
        this.data["saveTime"] = saveTime
        localStorage.setItem("saveTime", this.toString());
        localStorage.setItem(this.gameName, JSON.stringify(this.data));
    }

    /**
     * 上传数据
     */
    public static UpdateData(callback: Function, caller: any, isShowTip: boolean = false) {
        UserDataHelper.updateUserData(this.appid, this.gameName, this.openid, JSON.stringify(this.data), (code, msg, timestamp) => {
            this.offsetTime = new Date().getTime() - timestamp;
            if (code == 0 && !!msg) {
                localStorage.setItem("saveTime", timestamp.toString());
                this.data["saveTime"] = timestamp;
                if (isShowTip) {
                    console.log("【上传数据】成功!");
                }
            } else {
                if (isShowTip) {
                    console.warn("【上传数据】失败!");
                }
            }
            if (!!callback) {
                if (!!caller) {
                    callback.call(caller);
                } else {
                    callback();
                }
            }
        });
    }

    /**
     * 获取字符串数据
     * @param key 键值
     * @param defaultValue 默认数据 
     * @returns 
     */
    public static GetStringData(key: string, defaultValue: string = null): string {
        if (this.data.hasOwnProperty(key)) {
            return this.data[key];
        }
        return defaultValue;
    }

    /**
     * 获取Number数据
     * @param key 键值
     * @param defaultValue 默认数据
     * @returns 
     */
    public static GetNumberData(key: string, defaultValue: number = 0): number {
        if (this.data.hasOwnProperty(key)) {
            return this.data[key];
        }
        return defaultValue;
    }

    /**
     * 获取布尔数据
     * @param key 键值
     * @param defaultValue 默认数据
     * @returns 
     */
    public static GetBooleanData(key: string, defaultValue: boolean = true): boolean {
        if (this.data.hasOwnProperty(key)) {
            return this.data[key];
        }
        return defaultValue;
    }

    /**
     * 获取复杂数据（泛型T需要集成自DataBase）
     * @param key 键值
     * @param defaultValue 默认数据 
     * @returns 
     */
    public static GetData<T extends DataBase>(key: string, defaultValue: T = null): T {
        if (this.data.hasOwnProperty(key)) {
            return this.data[key] as T;
        }
        return defaultValue;
    }

    /**
     * 保存数据
     * @param key 存档键值
     * @returns 
     */
    public static SaveData(key: string): string {
        let str = JSON.stringify(this.data);
        localStorage.setItem(key, str);
        return str;
    }

    /**
     * 删除数据
     * @param callback 回调 
     * @param caller 作用域
     */
    public static DeleteData(callback: Function, caller: any) {
        this.data = {};
        this.UpdateData(callback, caller);
    }

}


